package com.gmadmin.entity.vo.user;


import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.gmadmin.common.Builder;
import com.gmadmin.common.Constants;
import com.gmadmin.entity.vo.menu.SysMenuVo;
import com.gmadmin.entity.vo.role.SysRoleVo;
import io.swagger.annotations.ApiModelProperty;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;


import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 登录验证自定义User信息返回结果
 *
 * @author zhangliang
 * @version 1.0
 * @date 2021/1/25 10:15
 */
@JsonInclude(JsonInclude.Include.NON_EMPTY)
public class UserPrincipal implements UserDetails {
    /**
     * 主键
     */
    @ApiModelProperty(value = "用户id")
    private Long id;

    /**
     * 用户名
     */
    @ApiModelProperty(value = "用户名称")
    private String username;

    /**
     * 密码
     */
    @JsonIgnore
    private String password;

    /**
     * 昵称
     */
    private String nickName;

    /**
     * 手机
     */
    private String phone;

    /**
     * 邮箱
     */
    private String email;

    /**
     * 生日
     */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime birthday;

    /**
     * 性别，男-1，女-2,这里我直接用的string
     */
    private String gender;

    /**
     * 状态，启用-1，禁用-0
     */
    private String status;

    /**
     * 头像
     */
    private String avatarName;
    /**
     * 创建时间
     */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private String createTime;

    /**
     * 更新时间
     */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private String updateTime;

    /**
     * 菜单组件地址
     */
    private List<String> component;

    /**
     * 用户角色
     */
    private Collection<? extends GrantedAuthority> authorities;


    public Long getId() {
        return id;
    }

    public List<String> getComponent() {
        return component;
    }


    public String getPhone() {
        return phone;
    }

    public String getEmail() {
        return email;
    }

    public LocalDateTime getBirthday() {
        return birthday;
    }


    public String getCreateTime() {
        return createTime;
    }

    public String getUpdateTime() {
        return updateTime;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public void setPassword(String password) {
        this.password = password;
    }


    public void setPhone(String phone) {
        this.phone = phone;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public void setBirthday(LocalDateTime birthday) {
        this.birthday = birthday;
    }


    public void setStatus(String status) {
        this.status = status;
    }

    public void setCreateTime(String createTime) {
        this.createTime = createTime;
    }

    public void setUpdateTime(String updateTime) {
        this.updateTime = updateTime;
    }

    public void setComponent(List<String> component) {
        this.component = component;
    }

    public void setAuthorities(Collection<? extends GrantedAuthority> authorities) {
        this.authorities = authorities;
    }

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        return authorities;
    }

    @Override
    public String getPassword() {
        return password;
    }

    @Override
    public String getUsername() {
        return username;
    }

    public String getAvatarName() {
        return avatarName;
    }

    public void setAvatarName(String avatarName) {
        this.avatarName = avatarName;
    }

    @Override
    public boolean isAccountNonExpired() {
        return true;
    }

    @Override
    public boolean isAccountNonLocked() {
        return true;
    }

    @Override
    public boolean isCredentialsNonExpired() {
        return true;
    }

    public String getNickName() {
        return nickName;
    }

    public void setNickName(String nickName) {
        this.nickName = nickName;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    @Override
    public boolean isEnabled() {
        return Objects.equals(this.status, Constants.ENABLE);
    }

    public static UserPrincipal create(SysUserVo user, List<SysRoleVo> roles, List<SysMenuVo> permissions) {
//        获取角色名称
        Set<SimpleGrantedAuthority> authorities = roles.stream()
                .map(sysRole -> new SimpleGrantedAuthority(sysRole.getName())).collect(Collectors.toSet());
        // 获取组件权限并过滤为是路由的

        List<String> components = permissions.stream()
                .filter(permission -> permission.getType() == 1)
                .map(SysMenuVo::getComponent).collect(Collectors.toList());


        return Builder.of(UserPrincipal::new)
                .with(UserPrincipal::setId, user.getId())
                .with(UserPrincipal::setUsername, user.getUsername())
                .with(UserPrincipal::setPassword, user.getPassword())
                .with(UserPrincipal::setNickName, user.getNickName())
                .with(UserPrincipal::setAvatarName, user.getAvatarName())
                .with(UserPrincipal::setPhone, user.getPhone())
                .with(UserPrincipal::setEmail, user.getEmail())
                .with(UserPrincipal::setBirthday, Objects.nonNull(user.getBirthday()) ? user.getBirthday() : null)
                .with(UserPrincipal::setGender, user.getGender())
                .with(UserPrincipal::setStatus, user.getEnabled())
                .with(UserPrincipal::setUpdateTime, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").format(user.getUpdateTime()))
                .with(UserPrincipal::setComponent, components)
                .with(UserPrincipal::setAuthorities, authorities)
                .build();

    }

}
